package com.kh.rationaldrugreview.neo4j.entity;

import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Property;
import org.springframework.data.neo4j.core.schema.Relationship;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import java.util.Set;

/**
 * Neo4j知识图谱实体定义
 */
public class KnowledgeGraphEntities {
    
    /**
     * 疾病实体
     */
    @Node("DISEASE")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class DiseaseNode {
        @Id @GeneratedValue
        private Long id;
        
        @Property("name")
        private String name;
        
        @Property("icd10Code")
        private String icd10Code;
        
        @Property("category")
        private String category;
        
        @Property("symptoms")
        private String symptoms;
        
        @Property("complications")
        private String complications;
        
        @Property("prevalence")
        private String prevalence;
        
        @Property("riskFactors")
        private String riskFactors;
        
        @Relationship(type = "HAS_SYMPTOM", direction = Relationship.Direction.OUTGOING)
        private Set<SymptomNode> hasSymptoms;
        
        @Relationship(type = "TREATED_BY", direction = Relationship.Direction.INCOMING)
        private Set<DrugNode> treatedByDrugs;
    }
    
    /**
     * 症状实体
     */
    @Node("SYMPTOM")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SymptomNode {
        @Id @GeneratedValue
        private Long id;
        
        @Property("name")
        private String name;
        
        @Property("description")
        private String description;
        
        @Property("severity")
        private String severity;
        
        @Property("frequency")
        private String frequency;
        
        @Property("bodySystem")
        private String bodySystem;
    }
    
    /**
     * 成分实体
     */
    @Node("INGREDIENT")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class IngredientNode {
        @Id @GeneratedValue
        private Long id;
        
        @Property("name")
        private String name;
        
        @Property("type")
        private String type; // 活性成分/辅料
        
        @Property("content")
        private String content;
        
        @Property("unit")
        private String unit;
        
        @Property("function")
        private String function;
        
        @Property("chemicalFormula")
        private String chemicalFormula;
        
        @Property("molecularWeight")
        private Double molecularWeight;
    }
    
    /**
     * 基因实体
     */
    @Node("GENE")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class GeneNode {
        @Id @GeneratedValue
        private Long id;
        
        @Property("symbol")
        private String symbol;
        
        @Property("fullName")
        private String fullName;
        
        @Property("chromosome")
        private String chromosome;
        
        @Property("polymorphisms")
        private String polymorphisms;
        
        @Property("clinicalSignificance")
        private String clinicalSignificance;
        
        @Relationship(type = "AFFECTS", direction = Relationship.Direction.OUTGOING)
        private Set<DrugNode> affectsDrugs;
    }
    
    /**
     * 酶实体
     */
    @Node("ENZYME")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class EnzymeNode {
        @Id @GeneratedValue
        private Long id;
        
        @Property("name")
        private String name;
        
        @Property("ecNumber")
        private String ecNumber;
        
        @Property("function")
        private String function;
        
        @Property("substrate")
        private String substrate;
        
        @Property("inhibitors")
        private String inhibitors;
        
        @Property("inducers")
        private String inducers;
        
        @Relationship(type = "METABOLIZES", direction = Relationship.Direction.OUTGOING)
        private Set<DrugNode> metabolizesDrugs;
    }
    
    /**
     * 不良反应实体
     */
    @Node("ADVERSE_REACTION")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class AdverseReactionNode {
        @Id @GeneratedValue
        private Long id;
        
        @Property("name")
        private String name;
        
        @Property("frequency")
        private String frequency;
        
        @Property("severity")
        private String severity;
        
        @Property("bodySystem")
        private String bodySystem;
        
        @Property("mechanism")
        private String mechanism;
        
        @Property("management")
        private String management;
        
        @Relationship(type = "CAUSED_BY", direction = Relationship.Direction.INCOMING)
        private Set<DrugNode> causedByDrugs;
    }
    
    /**
     * 用法用量实体
     */
    @Node("DOSAGE")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class DosageNode {
        @Id @GeneratedValue
        private Long id;
        
        @Property("population")
        private String population;
        
        @Property("route")
        private String route;
        
        @Property("dose")
        private String dose;
        
        @Property("frequency")
        private String frequency;
        
        @Property("duration")
        private String duration;
        
        @Property("maxDailyDose")
        private String maxDailyDose;
        
        @Property("adjustmentNeeded")
        private Boolean adjustmentNeeded;
        
        @Property("adjustmentCriteria")
        private String adjustmentCriteria;
    }
    
    /**
     * 禁忌症实体
     */
    @Node("CONTRAINDICATION")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ContraindicationNode {
        @Id @GeneratedValue
        private Long id;
        
        @Property("condition")
        private String condition;
        
        @Property("type")
        private String type; // 绝对禁忌/相对禁忌
        
        @Property("reason")
        private String reason;
        
        @Property("riskLevel")
        private String riskLevel;
        
        @Relationship(type = "CONTRAINDICATED_FOR", direction = Relationship.Direction.INCOMING)
        private Set<DrugNode> contraindicatedDrugs;
    }
    
    /**
     * 药物相互作用关系
     * Note: Relationship entities are not directly supported as standalone classes in Neo4j
     * These should be modeled as relationship properties in Cypher queries
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class InteractsWithRelationship {
        @Id @GeneratedValue
        private Long id;
        
        @Property("interactionLevel")
        private String interactionLevel;
        
        @Property("mechanism")
        private String mechanism;
        
        @Property("clinicalEffect")
        private String clinicalEffect;
        
        @Property("severity")
        private String severity;
        
        @Property("recommendation")
        private String recommendation;
        
        @Property("strength")
        private Integer strength;
    }
    
    /**
     * 治疗关系
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class TreatsRelationship {
        @Id @GeneratedValue
        private Long id;
        
        @Property("efficacy")
        private String efficacy;
        
        @Property("evidenceLevel")
        private String evidenceLevel;
        
        @Property("clinicalTrials")
        private String clinicalTrials;
        
        @Property("strength")
        private Integer strength;
    }
    
    /**
     * 代谢关系
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class MetabolizedByRelationship {
        @Id @GeneratedValue
        private Long id;
        
        @Property("pathway")
        private String pathway;
        
        @Property("percentage")
        private Double percentage;
        
        @Property("isMainPathway")
        private Boolean isMainPathway;
        
        @Property("strength")
        private Integer strength;
    }
}